package sanrenxing.kechenglx.dao.Impl;

import sanrenxing.kechenglx.dao.CourseSubjectDao;
import sanrenxing.kechenglx.domian.Course;
import sanrenxing.kechenglx.domian.CourseSubject;
import sanrenxing.utils.JdbcUtils;

import java.sql.Connection;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.util.ArrayList;
import java.util.List;
import java.util.Random;

/**
 * 功能：课程练习
 * 编写者：蒋玲苹
 * 日期：20201013
 * 版本：1.0
 */
public class CourseSubjectDaoImpl implements CourseSubjectDao {
    /**
     * 查询课程练习的题目编号
     *
     * @param courseId 课程编号
     * @return
     */
    @Override
    public List<Integer> subjectNum(int courseId) {
        // 定义一个集合保存
        List<Integer> map = new ArrayList<>();
        //声明数据库连接对象
        Connection conn = null;
        //声明预编译语句对象
        PreparedStatement pstmt = null;
        //定义影响行数的变量
        ResultSet rs = null;
        // 实列化数据层连接对象
        try {
            conn = JdbcUtils.getConnection();
            // 定义一个sql命令语句
            String sql = "select subjectId from subjects where courseId=?";
            // 实列化数据库连接对象
            pstmt = conn.prepareStatement(sql);
            // 给相应的占位符赋值
            pstmt.setInt(1, courseId);
            // 结果集对象
            rs = pstmt.executeQuery();
            while (rs.next()) {
                int subjectId = rs.getInt("subjectId");
                // 将题目编号添加到集合中
                map.add(subjectId);
            }

        } catch (SQLException e) {
            //运行时异常
            throw new RuntimeException(e.getMessage(), e);
        } finally {
            //释放资源
            JdbcUtils.close(rs, pstmt, conn);
        }
        // 返回集合
        return map;

    }


    /**
     * 根据课程编号取出题目
     *
     * @param courseId 课程编号
     * @return
     */
    @Override
    public CourseSubject getSubject(int courseId) {
        //定义数据库连接对象
        Connection conn = null;
        //定义预编译语句对象
        PreparedStatement pstmt = null;
        //声明结果集对象
        ResultSet rs = null;

        try {
            //实例化数据库连接对象
            conn = JdbcUtils.getConnection();
            //编写要执行的sql命令语句
            String sql = "select courseId,subjectId,subjectType,stem,optionA,optionB,optionC,optionD," +
                    "optionE,optionF,optionG,optionH,correct from subjects where subjectId=?";
            //实例化预编译语句对象
            pstmt = conn.prepareStatement(sql);
            //给sql命令语句中的占位符赋值
            pstmt.setInt(1, courseId);
            //执行sql命令语句
            rs = pstmt.executeQuery();

            //对结果集进行判断
            if (rs.next()) {
                //创建CourseSubject对象
                CourseSubject courseSubject = new CourseSubject();
                //题目编号
                courseSubject.setSubjectId(rs.getInt("subjectId"));
                //题目类型
                courseSubject.setStem(rs.getString("subjectType"));
                //题干
                courseSubject.setStem(rs.getString("stem"));
                //课程编号
                courseSubject.setCourseId(rs.getInt("courseId"));
                //创建选择项String数组
                String[] op = {"A", "B", "C", "D", "E", "F", "G", "H"};
                //定义一个选项存储不为空选项的字母
                String notNull = "";
                //排除空选项s:op空选择不需要打乱顺序
                for (String s : op) {
                    //取得选项的值+s
                    String selects = rs.getString("option" + s);
                    //selects判断是否有值
                    if (!selects.equals("") && !selects.equals(null)) {
                        //不为空选项的+=s
                        notNull += s;
                    }
                }

                //获得不为空选项个数
                int leng = notNull.length();
                //调用生成随机数方法，并传参需要生成随机数的个数为不为空选项的个数
                int[] randomArr = Random(leng);
                //定义一个值为0的i变量
                int i = 0;
                //定义一个保存正确答案状态的String类型数据correctNum
                String correctNum = "";
                //获取正确答案
                String correct = rs.getString("correct");
                //通过循环，以数字类型的数据保存正确答案状态
                for (int j = 0; j < op.length; j++) {
                    //答案长度等于1
                    if (correct.length() == 1 && correct.equals(op[j])) {
                        //单选题情况保存正确答案状态
                        correctNum = String.valueOf(j);
                        break;
                    } else if (correct.length() > 1) {//答案长度大于1
                        //多选题情况保存正确答案状态
                        for (int a = 0; a < correct.length(); a++) {
                            if (String.valueOf(correct.charAt(a)).equals(op[j])) {
                                //将多个答案依次转换为数字状态并上+","
                                correctNum += String.valueOf(j) + ",";
                            }
                        }
                    }
                }
                //定义空的字符串数组
                String[] correctArr = null;
                //将正确答案状态字符串转换为字符串数组
                if (correctNum.length() > 1) {
                    //去除最后一个逗号
                    correctNum = correctNum.substring(0, correctNum.length() - 1);
                    correctArr = correctNum.split(",");
                }
                //定义一个保存trues正确答案的字符串
                String trues = "";
                //将非空选项保存到字符数组中.toCharArray()
                char[] notNullArr = notNull.toCharArray();
                for (char c : notNullArr) {
                    //将char转换为String，方便使用equals
                    String sc = String.valueOf(c);
                    //将随机好的数字状态取出
                    int num = randomArr[i];
                    i++;
                    //判断选项
                    if (sc.equals("A")) {
                        //将随机题目保存到选项当中
                        courseSubject.setOptionA(rs.getString("option" + notNullArr[num] + ""));
                        //判断正确答案的状态和随机后的答案的状态是否相等，如果相等，则保存正确答案
                        if (correctArr == null) {
                            //单选题情况
                            if (Integer.parseInt(correctNum) == num) {
                                //正确答案A
                                trues = "A";
                            }
                        } else {
                            //多选题情况
                            for (int v = 0; v < correctArr.length; v++) {
                                if (Integer.parseInt(correctArr[v]) == num) {
                                    //正确答案+=A
                                    trues += "A";
                                }
                            }
                        }

                    } else if (sc.equals("B")) {
                        courseSubject.setOptionB(rs.getString("option" + notNullArr[num] + ""));
                        //判断正确答案的状态和随机后的答案的状态是否相等，如果相等，则保存正确答案
                        if (correctArr == null) {
                            //单选题情况
                            if (Integer.parseInt(correctNum) == num) {
                                //正确答案B
                                trues = "B";
                            }
                        } else {
                            //多选题情况
                            for (int v = 0; v < correctArr.length; v++) {
                                if (Integer.parseInt(correctArr[v]) == num) {
                                    //正确答案+=B
                                    trues += "B";
                                }
                            }
                        }
                    } else if (sc.equals("C")) {
                        courseSubject.setOptionC(rs.getString("option" + notNullArr[num] + ""));
                        //判断正确答案的状态和随机后的答案的状态是否相等，如果相等，则保存正确答案
                        if (correctArr == null) {
                            //单选题情况
                            if (Integer.parseInt(correctNum) == num) {
                                //正确答案C
                                trues = "C";
                            }
                        } else {//多选题情况
                            for (int v = 0; v < correctArr.length; v++) {
                                if (Integer.parseInt(correctArr[v]) == num) {
                                    //正确答案+=C
                                    trues += "C";
                                }
                            }
                        }
                    } else if (sc.equals("D")) {
                        courseSubject.setOptionD(rs.getString("option" + notNullArr[num] + ""));
                        //判断正确答案的状态和随机后的答案的状态是否相等，如果相等，则保存正确答案
                        if (correctArr == null) {
                            //单选题情况
                            if (Integer.parseInt(correctNum) == num) {
                                trues = "D";
                            }
                        } else {
                            //多选题情况
                            for (int v = 0; v < correctArr.length; v++) {
                                if (Integer.parseInt(correctArr[v]) == num) {
                                    //正确答案+=D
                                    trues += "D";
                                }
                            }
                        }
                    } else if (sc.equals("E")) {
                        courseSubject.setOptionE(rs.getString("option" + notNullArr[num] + ""));
                        //判断正确答案的状态和随机后的答案的状态是否相等，如果相等，则保存正确答案
                        if (correctArr == null) {
                            //单选题情况
                            if (Integer.parseInt(correctNum) == num) {
                                trues = "E";
                            }
                        } else {
                            //多选题情况
                            for (int v = 0; v < correctArr.length; v++) {
                                if (Integer.parseInt(correctArr[v]) == num) {
                                    //正确答案+=E
                                    trues += "E";
                                }
                            }
                        }
                    } else if (sc.equals("F")) {
                        courseSubject.setOptionF(rs.getString("option" + notNullArr[num] + ""));
                        //判断正确答案的状态和随机后的答案的状态是否相等，如果相等，则保存正确答案
                        if (correctArr == null) {
                            //单选题情况
                            if (Integer.parseInt(correctNum) == num) {
                                trues = "F";
                            }
                        } else {
                            //多选题情况
                            for (int v = 0; v < correctArr.length; v++) {
                                if (Integer.parseInt(correctArr[v]) == num) {
                                    //正确答案+=F
                                    trues += "F";
                                }
                            }
                        }
                    } else if (sc.equals("G")) {
                        courseSubject.setOptionG(rs.getString("option" + notNullArr[num] + ""));
                        //判断正确答案的状态和随机后的答案的状态是否相等，如果相等，则保存正确答案
                        if (correctArr == null) {
                            //单选题情况
                            if (Integer.parseInt(correctNum) == num) {
                                trues = "G";
                            }
                        } else {
                            //多选题情况
                            for (int v = 0; v < correctArr.length; v++) {
                                if (Integer.parseInt(correctArr[v]) == num) {
                                    //正确答案+=G
                                    trues += "G";
                                }
                            }
                        }
                    } else if (sc.equals("H")) {
                        courseSubject.setOptionH(rs.getString("option" + notNullArr[num] + ""));
                        //判断正确答案的状态和随机后的答案的状态是否相等，如果相等，则保存正确答案
                        if (correctArr == null) {
                            //单选题情况
                            if (Integer.parseInt(correctNum) == num) {
                                trues = "H";
                            }
                        } else {
                            //多选题情况
                            for (int v = 0; v < correctArr.length; v++) {
                                if (Integer.parseInt(correctArr[v]) == num) {
                                    //正确答案+=H
                                    trues += "H";
                                }
                            }
                        }
                    }
                }

                //将正确答案保存到对象当中
                courseSubject.setCorrect(trues);
                //返回一个题目对象
                return courseSubject;
            }
        } catch (SQLException e) {
            //运行时异常
            new RuntimeException(e.getMessage(), e);
        } finally {
            //释放资源
            JdbcUtils.close(rs, pstmt, conn);
        }
        return null;
    }




    /**
     * 查询所有课程
     *
     * @return
     */
    @Override
    public List<Course> findCourse() {
        //声明数据库连接对象
        Connection conn=null;
        //声明预编译语句对象
        PreparedStatement pstmt=null;
        //声明结果集对象
        ResultSet rs=null;
        //创建一个Course集合
        List<Course> courseList=new ArrayList<>();
        try {
            //实例化数据库连接对象
            conn= JdbcUtils.getConnection();
            //编写要执行的sql命令语句
            String sql="select * from course";
            //实例化预编译语句对象
            pstmt=conn.prepareStatement(sql);
            //执行sql命令语句
            rs=pstmt.executeQuery();
            //对结果集进行循环
            while(rs.next()){
                //创建Course课程对象
                Course course=new Course();
                course.setCourseId(rs.getInt("courseId"));
                course.setCourseName(rs.getString("courseName"));
                courseList.add(course);
            }
        } catch (SQLException e) {
            //运行时异常
            new RuntimeException(e.getMessage(),e);
        }finally{
            //释放资源
            JdbcUtils.close(rs,pstmt,conn);
        }
        //返回课程集合
        return courseList;
    }

    /**
     * 查询课程的行数
     *
     * @return
     */
    @Override
    public int count() {
        //声明数据库连接对象
        Connection conn=null;
        //声明预编译语句对象
        PreparedStatement pstmt=null;
        //声明结果集对象
        ResultSet rs=null;
        //定义总行数
        int count=0;
        try {
            //实例化数据库连接对象
            conn= JdbcUtils.getConnection();
            //编写要执行的sql命令语句
            String sql="select count(*) as count from course";
            //实例化预编译语句对象
            pstmt=conn.prepareStatement(sql);
            //执行sql命令语句
            rs=pstmt.executeQuery();
            //对结果进行判断
            if (rs.next()){
                count=rs.getInt("count");
                return count;
            }
        } catch (SQLException e) {
            //运行时异常
            new RuntimeException(e.getMessage(),e);
        }
        return 0;
    }

    /**
     * 生成随机数方法
     *
     * @param length
     * @return
     */
    @Override
    public int[] Random(int length) {
        // 定义一个随机数长度
        int[] a = new int[length];
        Random random = new Random();
        // 记录有效数的随机数
        int count = 0;
        while (count < a.length) {
            // 用标志的量
            boolean flag = true;
            int r = random.nextInt(length) + 1;
            for (int i = 0; i < a.length; i++) {
                if (r == a[i]) {
                    flag = false;
                    break;
                }
            }
            if (flag) {
                //为什么要减一呢，因为通过上面的判断是不能取到0的，但是根据长度获取长度类的数字需要0，所以减一。
                a[count] = r;
                count++;
            }
        }
        // 将原有的随机数依次递减
        for (int j = 0; j < a.length; j++) {
            a[j] = a[j] - 1;
        }
        return a;
    }
}
